package com.cyw.common.utils;

import java.math.BigDecimal;
import java.util.Optional;

import static com.cyw.common.utils.StreamUtils.prop;
import static java.math.BigDecimal.ZERO;

/**
 * 金额计算
 */
public class MoneyUtils {
    public static final BigDecimal DEFAULT_MULTIPLE_HUNDRED = new BigDecimal(100);
    public static final BigDecimal DEFAULT_MULTIPLE_TEN = new BigDecimal(10);

    public static final BigDecimal DEFAULT_MULTIPLE_THOUSAND = new BigDecimal(1000);

    // 小数后n位
    public static final int DECIMAL_BIT_TWO = BigDecimal.ROUND_HALF_UP;

    //============================================= 元 转 分 -- start =======================================================

    /**
     * 元转分
     *
     * @param yen
     * @return
     */
    public static Long yen2Cent(BigDecimal yen) {
        return DecimalUtils.multiply(DecimalUtils.DECIMAL_BIT_TWO, yen, DEFAULT_MULTIPLE_HUNDRED).longValue();
    }

    /**
     * 将元转为分
     *
     * @param yen
     * @return
     */
    public static Integer yen2CentInt(BigDecimal yen) {
        return prop(yen, y -> y.multiply(DEFAULT_MULTIPLE_HUNDRED).intValue(), 0);
    }

    //============================================= 元 转 分 -- end =======================================================


    //============================================= 分 转 元 -- start  =======================================================

    /**
     * 分转元，四舍五入到"分"，即保留两位小数
     *
     * @param cent
     * @return
     */
    public static BigDecimal cent2Yen(Integer cent) {
        return prop(
                convert(cent),
                c -> c.divide(DEFAULT_MULTIPLE_HUNDRED, DECIMAL_BIT_TWO)
        );
    }

    /**
     * 分转元，四舍五入到"分"，即保留两位小数
     *
     * @param cent
     * @return
     */
    public static BigDecimal cent2Yen(Long cent) {
        return prop(
                convert(cent),
                c -> c.divide(DEFAULT_MULTIPLE_HUNDRED, DECIMAL_BIT_TWO)
        );
    }


    //============================================= 分 转 元 -- end  =======================================================


    private static BigDecimal convert(Long value) {
        return Optional.ofNullable(value)
                .map(BigDecimal::valueOf)
                .orElse(ZERO);
    }

    private static BigDecimal convert(Integer value) {
        return Optional.ofNullable(value)
                .map(BigDecimal::valueOf)
                .orElse(ZERO);
    }


    /**
     * 如果是小数结果就是小数.如果是整数.返回就是整数.
     * 避免出现整数后面有.00的情况.
     * 以“,”分组，三个数字一组
     *
     * @param price
     * @return
     */
    public static String toSmartPriceWithGroup(BigDecimal price) {
        return DecimalUtils.decimalFormat(price, "###,###.##");
    }

    /**
     * 如果是小数结果就是小数.如果是整数.返回就是整数.
     * 避免出现整数后面有.00的情况.
     * 无分组
     *
     * @param price
     * @return
     */
    public static String toSmartPrice(BigDecimal price) {
        return DecimalUtils.decimalFormat(price, "###.##");
    }

}
